#include <bits/stdc++.h>  // 头文件：常用库（万能头文件，考级比赛用)

#include <algorithm>  // 头文件：常用算法库
#include <cmath>      // 头文件：数学函数库
#include <iomanip>    // 头文件：格式控制（限制小数位数）
#include <iostream>   // 头文件：输入输出流
#include <string>     // 头文件：字符串
using namespace std;  // 命名空间：标准库

#define PI 3.14  // 定义常量 PI 如果修改值会报错

int main() {
  // 梦开始的地方：输出 Hello World!
  // endl 输出换行并清空缓存区 \n 也可以输出换行符
  cout << "Hello World!" << endl;
  // 整型
  // 关键字：int
  // 占用空间：4 Byte
  // 1 Byte = 8 bit
  // 整型变量的二进制表示：[第一位，符号位，0 为正数，1 为负数] [31位 ~ 25位]
  // +1: 0 000 0000 0000 0000 0000 0000 0000 0001
  // -1: 1 000 0000 0000 0000 0000 0000 0000 0001
  // 其他数字类型：float, double, long long
  // 变量命名规则：数字、字母、下划线组成，不能以数字开头
  // 有符号整型变量范围：-2^31 ~ 2^31 - 1
  int a = 1;              // 定义整型变量并赋值为 1
  float b = 1.5;          // 浮点型变量
  double c = 1.23456789;  // 双精度浮点型变量
  // 长整型
  long long d = 123456789012345678901234567890123456789;
  // 数学运算符：+ - * / % 加 减 乘 除 取余
  // 限定小数位数
  cout << fixed << setprecision(2) << c << endl;
  // 输入输出
  int temp = 0;
  cin >> temp;
  cout << temp << endl;
  // 更多输入输出方式
  scanf("%d", &temp);
  printf("%d", temp);
  // 布尔型
  // 关键字：bool
  bool yes = true;  // 定义布尔变量值为真
  bool no = false;  // 定义布尔变量值为假
  // 逻辑运算符：与 && 或 || 非 !
  // 关系运算符：大于 > 小于 < 大于等于 >= 小于等于 <= 等于 == 不等于 !=
  // 条件分支语句：if-else switch-case
  if (a > 0) {
    cout << "a 是正数" << endl;
  } else if (a < 0) {
    cout << "a 是负数" << endl;
  } else {
    cout << "a 是零" << endl;
  }
  // 三目运算符：a ? b : c if-else 简写
  cout << (a > 0 ? "a 是正数" : (a < 0 ? "a 是负数" : "a 是零")) << endl;
  // 利用 % 判断奇偶
  if (a % 2 == 0) {
    cout << "a 是偶数" << endl;
  } else {
    cout << "a 是奇数" << endl;
  }
  // 利用 / 和 % 倒序输出数字各位值
  int num = 12345;
  while (num > 0) {
    cout << num % 10 << " ";
    num /= 10;
  }
  // 循环语句：for while while-do do-while
  // 数组
  int arr[10] = {2, 3, 4, 5, 1, 0, 9, 8, 7, 6};
  // 通过 for 循环给数组赋初值
  for (int i = 0; i < 10; i++) {
    cin >> arr[i];
  }
  // 通过 for 循环打印数组
  for (int i = 0; i < 10; i++) {
    cout << arr[i] << " ";
  }
  sort(arr, arr + 10);     // 排序
  reverse(arr, arr + 10);  // 翻转数组

  // 二阶
  // 字符型
  // 关键字：char
  // 占用空间：1 Byte
  char c = 'A';           // 定义字符变量
  cout << c + 0 << endl;  // 打印字符 ASCLL 码
  char c2 = c + 1;        // 通过 + 运算符，ASCLL 码加 1
  cout << c2 << endl;     // A + 1 -> B
  // 字符串
  // 关键字：string
  string str1 = "nihao";  // 定义字符串，并赋值
  string a = "hello", b = "world";
  string str2 = a + b;  // 字符串拼接
  string s;
  // cin >> s; // cin 输入字符串的值，无法包含空格
  getline(cin, s);              // getline() 输入字符串的值，可以包含空格
  reverse(s.begin(), s.end());  // reverse() 翻转字符串
  int len = s.size();           // str.size() 获取字符串长度
  int index = s.find("hello");  // str.find() 查找字符串中第一个 hello 的位置
  // 没有则返回 -1 string::npos
  string str3;
  str3 = s.substr(0, 5);  // str.substr() 截取字符串，开始位置为 0，长度为 5
  // 字符串做比较
  if (a == b) {
    cout << "a==b" << endl;
  }
  // 二维数组
  // 定义函数
  int add(int a, int b) {
    return a + b;
  }
  // 调用函数
  cout << add(1, 2) << endl;
  // 默认参数
  void print(string message = "hello") {
    cout << message << endl;
  }
  // 递归函数：求阶乘
  int factorial(int n) {
    if (n == 1) {
      return 1;
    } else {
      return n * factorial(n - 1);
    }
  }
  // 递归函数：求斐波那契数列
  int fibonacci(int n) {
    if (n == 1 || n == 2) {
      return 1;
    } else {
      return fibonacci(n - 1) + fibonacci(n - 2);
    }
  }
  // 常用数学函数
  pow(2, 4);   // 幂函数 2^4 = 16
  sqrt(4);     // 平方根 4^0.5 = 2
  abs(3 - 5);  // 绝对值 |3-5| = 2
  log(10);     // 对数函数 log10(10) = 1
  exp(2);      // 指数函数 e^2
  sin(3.14);   // 正弦函数
  cos(3.14);   // 余弦函数
  tan(3.14);   // 正切函数
  atan(1);     // 反正切函数
  asin(0.5);   // 反正弦函数
  acos(0.5);   // 反余弦函数
  // 结构体
  // 定义学生结构体
  struct stu {
    int age;
    char name[20];
    int score;
  };
  // 定义学生类型变量
  stu zhangsan = {18, "张三", 100};
  // 访问结构体成员
  cout << "姓名：" << zhangsan.name << '\n';
  cout << "年龄：" << zhangsan.age << '\n';
  cout << "成绩：" << zhangsan.score << endl;
  // 指针
  int a = 10;
  int* p1 = &a;  // 定义指针 p1 通过取地址符 & 赋初值
  int arr2[10] = {1, 2, 3};
  int* p2 = arr2;  // 定义指针 p2 等价于 &arr2[0]
  // 打印指针（地址）
  cout << p1 << '\n';
  cout << arr2 << '\n';
  // *p 解引用打印指针指向的值
  cout << *p1 << '\n';
  cout << *p2 << '\n';
  // for 循环 + 指针 打印数组元素
  for (int i = 0; i < 10; i++) {
    cout << *(p2 + i) << '\n';
  }
}